{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.metrics import accuracy_score\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_path = \"../data/adult.data\"\n",
    "test_path = \"../data/adult.test\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "col_labels = ['age', 'workclass', 'fnlwgt', 'education', 'education_num', 'marital_status',\n",
    "              'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',\n",
    "              'hours_per_week', 'native_country', 'wage_class']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_df = pd.read_csv(train_path, names=col_labels)\n",
    "test_data_df = pd.read_csv(test_path, names=col_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_data_df = test_data_df[1:].reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>workclass</th>\n",
       "      <th>fnlwgt</th>\n",
       "      <th>education</th>\n",
       "      <th>education_num</th>\n",
       "      <th>marital_status</th>\n",
       "      <th>occupation</th>\n",
       "      <th>relationship</th>\n",
       "      <th>race</th>\n",
       "      <th>sex</th>\n",
       "      <th>capital_gain</th>\n",
       "      <th>capital_loss</th>\n",
       "      <th>hours_per_week</th>\n",
       "      <th>native_country</th>\n",
       "      <th>wage_class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>39</td>\n",
       "      <td>State-gov</td>\n",
       "      <td>77516</td>\n",
       "      <td>Bachelors</td>\n",
       "      <td>13</td>\n",
       "      <td>Never-married</td>\n",
       "      <td>Adm-clerical</td>\n",
       "      <td>Not-in-family</td>\n",
       "      <td>White</td>\n",
       "      <td>Male</td>\n",
       "      <td>2174</td>\n",
       "      <td>0</td>\n",
       "      <td>40</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&lt;=50K</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>50</td>\n",
       "      <td>Self-emp-not-inc</td>\n",
       "      <td>83311</td>\n",
       "      <td>Bachelors</td>\n",
       "      <td>13</td>\n",
       "      <td>Married-civ-spouse</td>\n",
       "      <td>Exec-managerial</td>\n",
       "      <td>Husband</td>\n",
       "      <td>White</td>\n",
       "      <td>Male</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>13</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&lt;=50K</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>38</td>\n",
       "      <td>Private</td>\n",
       "      <td>215646</td>\n",
       "      <td>HS-grad</td>\n",
       "      <td>9</td>\n",
       "      <td>Divorced</td>\n",
       "      <td>Handlers-cleaners</td>\n",
       "      <td>Not-in-family</td>\n",
       "      <td>White</td>\n",
       "      <td>Male</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>40</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&lt;=50K</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>53</td>\n",
       "      <td>Private</td>\n",
       "      <td>234721</td>\n",
       "      <td>11th</td>\n",
       "      <td>7</td>\n",
       "      <td>Married-civ-spouse</td>\n",
       "      <td>Handlers-cleaners</td>\n",
       "      <td>Husband</td>\n",
       "      <td>Black</td>\n",
       "      <td>Male</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>40</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&lt;=50K</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>28</td>\n",
       "      <td>Private</td>\n",
       "      <td>338409</td>\n",
       "      <td>Bachelors</td>\n",
       "      <td>13</td>\n",
       "      <td>Married-civ-spouse</td>\n",
       "      <td>Prof-specialty</td>\n",
       "      <td>Wife</td>\n",
       "      <td>Black</td>\n",
       "      <td>Female</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>40</td>\n",
       "      <td>Cuba</td>\n",
       "      <td>&lt;=50K</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   age          workclass  fnlwgt   education  education_num  \\\n",
       "0   39          State-gov   77516   Bachelors             13   \n",
       "1   50   Self-emp-not-inc   83311   Bachelors             13   \n",
       "2   38            Private  215646     HS-grad              9   \n",
       "3   53            Private  234721        11th              7   \n",
       "4   28            Private  338409   Bachelors             13   \n",
       "\n",
       "        marital_status          occupation    relationship    race      sex  \\\n",
       "0        Never-married        Adm-clerical   Not-in-family   White     Male   \n",
       "1   Married-civ-spouse     Exec-managerial         Husband   White     Male   \n",
       "2             Divorced   Handlers-cleaners   Not-in-family   White     Male   \n",
       "3   Married-civ-spouse   Handlers-cleaners         Husband   Black     Male   \n",
       "4   Married-civ-spouse      Prof-specialty            Wife   Black   Female   \n",
       "\n",
       "   capital_gain  capital_loss  hours_per_week  native_country wage_class  \n",
       "0          2174             0              40   United-States      <=50K  \n",
       "1             0             0              13   United-States      <=50K  \n",
       "2             0             0              40   United-States      <=50K  \n",
       "3             0             0              40   United-States      <=50K  \n",
       "4             0             0              40            Cuba      <=50K  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>age</th>\n",
       "      <th>workclass</th>\n",
       "      <th>fnlwgt</th>\n",
       "      <th>education</th>\n",
       "      <th>education_num</th>\n",
       "      <th>marital_status</th>\n",
       "      <th>occupation</th>\n",
       "      <th>relationship</th>\n",
       "      <th>race</th>\n",
       "      <th>sex</th>\n",
       "      <th>capital_gain</th>\n",
       "      <th>capital_loss</th>\n",
       "      <th>hours_per_week</th>\n",
       "      <th>native_country</th>\n",
       "      <th>wage_class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>25</td>\n",
       "      <td>Private</td>\n",
       "      <td>226802.0</td>\n",
       "      <td>11th</td>\n",
       "      <td>7.0</td>\n",
       "      <td>Never-married</td>\n",
       "      <td>Machine-op-inspct</td>\n",
       "      <td>Own-child</td>\n",
       "      <td>Black</td>\n",
       "      <td>Male</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>40.0</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&lt;=50K.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>38</td>\n",
       "      <td>Private</td>\n",
       "      <td>89814.0</td>\n",
       "      <td>HS-grad</td>\n",
       "      <td>9.0</td>\n",
       "      <td>Married-civ-spouse</td>\n",
       "      <td>Farming-fishing</td>\n",
       "      <td>Husband</td>\n",
       "      <td>White</td>\n",
       "      <td>Male</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>50.0</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&lt;=50K.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>28</td>\n",
       "      <td>Local-gov</td>\n",
       "      <td>336951.0</td>\n",
       "      <td>Assoc-acdm</td>\n",
       "      <td>12.0</td>\n",
       "      <td>Married-civ-spouse</td>\n",
       "      <td>Protective-serv</td>\n",
       "      <td>Husband</td>\n",
       "      <td>White</td>\n",
       "      <td>Male</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>40.0</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&gt;50K.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>44</td>\n",
       "      <td>Private</td>\n",
       "      <td>160323.0</td>\n",
       "      <td>Some-college</td>\n",
       "      <td>10.0</td>\n",
       "      <td>Married-civ-spouse</td>\n",
       "      <td>Machine-op-inspct</td>\n",
       "      <td>Husband</td>\n",
       "      <td>Black</td>\n",
       "      <td>Male</td>\n",
       "      <td>7688.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>40.0</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&gt;50K.</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>18</td>\n",
       "      <td>?</td>\n",
       "      <td>103497.0</td>\n",
       "      <td>Some-college</td>\n",
       "      <td>10.0</td>\n",
       "      <td>Never-married</td>\n",
       "      <td>?</td>\n",
       "      <td>Own-child</td>\n",
       "      <td>White</td>\n",
       "      <td>Female</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>30.0</td>\n",
       "      <td>United-States</td>\n",
       "      <td>&lt;=50K.</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  age   workclass    fnlwgt      education  education_num  \\\n",
       "0  25     Private  226802.0           11th            7.0   \n",
       "1  38     Private   89814.0        HS-grad            9.0   \n",
       "2  28   Local-gov  336951.0     Assoc-acdm           12.0   \n",
       "3  44     Private  160323.0   Some-college           10.0   \n",
       "4  18           ?  103497.0   Some-college           10.0   \n",
       "\n",
       "        marital_status          occupation relationship    race      sex  \\\n",
       "0        Never-married   Machine-op-inspct    Own-child   Black     Male   \n",
       "1   Married-civ-spouse     Farming-fishing      Husband   White     Male   \n",
       "2   Married-civ-spouse     Protective-serv      Husband   White     Male   \n",
       "3   Married-civ-spouse   Machine-op-inspct      Husband   Black     Male   \n",
       "4        Never-married                   ?    Own-child   White   Female   \n",
       "\n",
       "   capital_gain  capital_loss  hours_per_week  native_country wage_class  \n",
       "0           0.0           0.0            40.0   United-States     <=50K.  \n",
       "1           0.0           0.0            50.0   United-States     <=50K.  \n",
       "2           0.0           0.0            40.0   United-States      >50K.  \n",
       "3        7688.0           0.0            40.0   United-States      >50K.  \n",
       "4           0.0           0.0            30.0   United-States     <=50K.  "
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_data_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x1f1a588b908>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.distplot(train_data_df['age'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x1f1a798d888>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.distplot(train_data_df['hours_per_week'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_df = train_data_df.replace(' ?', np.nan)\n",
    "test_data_df = test_data_df.replace(' ?', np.nan)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 32561 entries, 0 to 32560\n",
      "Data columns (total 15 columns):\n",
      " #   Column          Non-Null Count  Dtype \n",
      "---  ------          --------------  ----- \n",
      " 0   age             32561 non-null  int64 \n",
      " 1   workclass       30725 non-null  object\n",
      " 2   fnlwgt          32561 non-null  int64 \n",
      " 3   education       32561 non-null  object\n",
      " 4   education_num   32561 non-null  int64 \n",
      " 5   marital_status  32561 non-null  object\n",
      " 6   occupation      30718 non-null  object\n",
      " 7   relationship    32561 non-null  object\n",
      " 8   race            32561 non-null  object\n",
      " 9   sex             32561 non-null  object\n",
      " 10  capital_gain    32561 non-null  int64 \n",
      " 11  capital_loss    32561 non-null  int64 \n",
      " 12  hours_per_week  32561 non-null  int64 \n",
      " 13  native_country  31978 non-null  object\n",
      " 14  wage_class      32561 non-null  object\n",
      "dtypes: int64(6), object(9)\n",
      "memory usage: 3.7+ MB\n",
      "None\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 16281 entries, 0 to 16280\n",
      "Data columns (total 15 columns):\n",
      " #   Column          Non-Null Count  Dtype  \n",
      "---  ------          --------------  -----  \n",
      " 0   age             16281 non-null  object \n",
      " 1   workclass       15318 non-null  object \n",
      " 2   fnlwgt          16281 non-null  float64\n",
      " 3   education       16281 non-null  object \n",
      " 4   education_num   16281 non-null  float64\n",
      " 5   marital_status  16281 non-null  object \n",
      " 6   occupation      15315 non-null  object \n",
      " 7   relationship    16281 non-null  object \n",
      " 8   race            16281 non-null  object \n",
      " 9   sex             16281 non-null  object \n",
      " 10  capital_gain    16281 non-null  float64\n",
      " 11  capital_loss    16281 non-null  float64\n",
      " 12  hours_per_week  16281 non-null  float64\n",
      " 13  native_country  16007 non-null  object \n",
      " 14  wage_class      16281 non-null  object \n",
      "dtypes: float64(5), object(10)\n",
      "memory usage: 1.9+ MB\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "print(train_data_df.info())\n",
    "print(test_data_df.info())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset = pd.concat([train_data_df,test_data_df],axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([' <=50K', ' >50K', ' <=50K.', ' >50K.'], dtype=object)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset['wage_class'].unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset['wage_class'] = dataset.wage_class.replace({' <=50K.': ' <=50K', ' >50K.': ' >50K'})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([' <=50K', ' >50K'], dtype=object)"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataset['wage_class'].unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "cate_features = []\n",
    "for feature in dataset.columns:\n",
    "    if dataset[feature].dtype == 'object':\n",
    "        dataset[feature] = pd.Categorical(dataset[feature]).codes\n",
    "        cate_features.append(feature)\n",
    "cate_features.remove('wage_class')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "features = dataset.drop('wage_class',axis=1)\n",
    "labels = dataset['wage_class']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "train_features, test_features = features[:train_data_df.shape[0]], features[train_data_df.shape[0]:]\n",
    "train_labels, test_labels = labels[:train_data_df.shape[0]], labels[train_data_df.shape[0]:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "import lightgbm as lgb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = lgb.LGBMClassifier(boosting_type='gbdt',num_leaves=15,max_depth=4,learning_rate=0.01)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LGBMClassifier(boosting_type='gbdt', class_weight=None, colsample_bytree=1.0,\n",
       "               importance_type='split', learning_rate=0.01, max_depth=4,\n",
       "               min_child_samples=20, min_child_weight=0.001, min_split_gain=0.0,\n",
       "               n_estimators=100, n_jobs=-1, num_leaves=15, objective=None,\n",
       "               random_state=None, reg_alpha=0.0, reg_lambda=0.0, silent=True,\n",
       "               subsample=1.0, subsample_for_bin=200000, subsample_freq=0)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(train_features,train_labels,categorical_feature=cate_features)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training accuracy score: 0.84288, test accuracy score: 0.81733\n"
     ]
    }
   ],
   "source": [
    "training_score = accuracy_score(model.predict(train_features),train_labels)\n",
    "testing_score = accuracy_score(model.predict(test_features),test_labels)\n",
    "print(\"Training accuracy score: %.5f, test accuracy score: %.5f\" % (training_score,testing_score))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torch.optim import Adam\n",
    "import torch.nn.init as init\n",
    "from torch.utils.data import TensorDataset, DataLoader\n",
    "from tqdm import tqdm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_data_df = train_data_df.dropna()\n",
    "test_data_df = test_data_df.dropna()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset = pd.concat([train_data_df,test_data_df],axis=0)\n",
    "dataset['wage_class'] = dataset.wage_class.replace({' <=50K.': ' <=50K', ' >50K.': ' >50K'})\n",
    "dataset['wage_class'] = pd.Categorical(dataset['wage_class']).codes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "for cate_col in cate_features:\n",
    "    tmp = pd.get_dummies(dataset[cate_col])\n",
    "    dataset.drop(cate_col, axis=1,inplace=True)\n",
    "    dataset = pd.concat([dataset,tmp], axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Model(nn.Module):\n",
    "    def __init__(self,feature_num):\n",
    "        super(Model, self).__init__()\n",
    "        self.fc1 = nn.Linear(feature_num, 2*feature_num, bias=True)\n",
    "        self.fc2 = nn.Linear(2*feature_num, 2*feature_num, bias=True)\n",
    "        self.fc3 = nn.Linear(2*feature_num, 2, bias=True)\n",
    "    def forward(self, x):\n",
    "        x = F.softmax(self.fc1(x))\n",
    "        x = F.dropout(x, p=0.5)\n",
    "        x = F.softmax(self.fc2(x))\n",
    "        x = F.dropout(x, p=0.5)\n",
    "        x = F.sigmoid(self.fc3(x))\n",
    "        return x\n",
    "\n",
    "    def _initialize_weights(self):\n",
    "        for m in self.modules():\n",
    "            print(m)\n",
    "            if isinstance(m, nn.Linear):\n",
    "                init.xavier_uniform_(m.weight, gain=1)\n",
    "                print(m.weight)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_set = dataset[:train_data_df.shape[0]]\n",
    "test_set = dataset[train_data_df.shape[0]:]\n",
    "train_features, train_labels = train_set.drop('wage_class', axis=1), train_set['wage_class']\n",
    "test_features, test_labels = test_set.drop('wage_class', axis=1), test_set['wage_class']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "torch_dataset = TensorDataset(torch.FloatTensor(train_features.values), torch.LongTensor(train_labels.tolist()))\n",
    "test_features_tensor = torch.FloatTensor(test_features.values)\n",
    "\n",
    "train_loader = DataLoader( \n",
    "        dataset=torch_dataset,\n",
    "        batch_size=128,\n",
    "        shuffle=True,\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = Model(train_features.shape[1])\n",
    "cross_entropy_loss = nn.CrossEntropyLoss()\n",
    "optimizer = Adam(model.parameters(), lr=1e-3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████| 20/20 [00:43<00:00,  2.16s/it]\n"
     ]
    }
   ],
   "source": [
    "for epoch in tqdm(range(20)):\n",
    "    for step, (batch_x, batch_y) in enumerate(train_loader):\n",
    "        pred = model(batch_x)\n",
    "        loss = cross_entropy_loss(pred, batch_y)\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()         # backward\n",
    "        optimizer.step()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_predict = model(torch.FloatTensor(train_features.values)).data.numpy()\n",
    "test_predict = model(torch.FloatTensor(test_features.values)).data.numpy()\n",
    "training_score = accuracy_score(np.argmax(train_predict, axis=1),train_labels)\n",
    "testing_score = accuracy_score(np.argmax(test_predict, axis=1),test_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training accuracy score: 0.75108, test accuracy score: 0.75432\n"
     ]
    }
   ],
   "source": [
    "print(\"Training accuracy score: %.5f, test accuracy score: %.5f\" % (training_score,testing_score))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
